package cz.cuni.amis.pogamut.episodic.decisions;

import java.io.Serializable;

/**
 * <code>AffordanceSlot</code> is a node type that can be attached to
 * <code>Action</code> or <code>Intention</code> nodes of the decision tree.
 * <code>AffordanceSlot</code> is not extending the <code>Node</code>
 * base class. When a slot is attached to a node, it means that in order
 * to perform (satisfy) the node some object satisfying the slot type must
 * be located first. Any item of the same type as the slot can be used to
 * fill it. No two slots of the same type can be attached to one node.
 * <p>
 * These slots in the decision tree structure are only basis for creation
 * of actual <code>ObjectSlot</code>s in the agent's memory that will be
 * linked with satisfying <code>ObjectNode</code>s.
 * <p>
 * Apart from material objects types, there can be slot of other
 * types like time or place. These slots are also needed to be filled and
 * they provide additional information about performance of the parent node.
 * For example the slot of type time can be linked with the object node
 * representing afternoon.
 *
 * @author Michal Cermak
 */
public class AffordanceSlot implements Serializable {
    /**
     * Determines if a de-serialized file is compatible with this class.
     *
     * Maintainers must change this value if and only if the new version
     * of this class is not compatible with old versions. See Sun docs
     * for <a href=http://java.sun.com/products/jdk/1.1/docs/guide
     * /serialization/spec/version.doc.html> details. </a>
     *
     * Not necessary to include in first version of the class, but
     * included here as a reminder of its importance.
     */
    private static final long serialVersionUID = 1L;


    /**
     * Type of a slot specifies the class of items that can satisfy (fill)
     * the affordance slot. Any item of same item type can be linked with
     * with the slot and no item that is not of this type cannot be linked
     * with it.
     */
    String type;

    /**
     * Unique ID of the slot. Used as an ID of vertex representing
     * this node when visualizing decision tree.
     */
    private int id = 0;

    /**
     * Because ID of decision nodes and slots are not set automatically
     * this indicator determines whether it is OK to retreive the ID.
     * ID that was not set yet, cannot be retreived.
     */
    private boolean idSet = false;

    /**
     * Instantiate the slot by providing its type.
     * <p>
     * No two slots of the same type can be attached on one node.
     *
     * @param   type    Type of the new slot.
     */
    public AffordanceSlot(String _type) {
        type = _type;
    }

    /**
     * Getter method for the <code>type</code> variable.
     *
     * @return  Returns the type of this slot specifying the class of items
     * that can satisfy (fill) it. Any item of same item type can be linked with
     * with the slot and no item that is not of this type cannot be linked
     * with it.
     */
    public String getType() {
        return type;
    }

    /**
     * This method sets the unique ID of the slot. Once set it cannot be changed.
     * It is the ID of vertex representing this node when visualizing decision tree.
     *
     * @param newId The ID of this node.
     */
    public boolean setId(int newId) {
        if (idSet) return false;
        idSet = true;
        id = newId;
        return true;
    }

    /**
     * Getter method for the <code>id</code> variable.
     *
     * @return  Returns the unique ID of the slot that is used as an ID of vertex representing
     * this node when visualizing decision tree.
     * @throws  Throws exception when trying to retrive ID that was not set yet.
     */
    public int getId() {
        if (!idSet) throw new RuntimeException("Node id not set.");
        return id;
    }
}
